﻿//-----------------------------------------------------------------------
// <copyright file="Translation.cs" company="FCIS">
//     Company copyright tag.
// </copyright>
//-----------------------------------------------------------------------

namespace IPPackage.ImageOperation
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Text;

    /// <summary>
    /// translation of image
    /// </summary>
    public class Translation : Open
    {
        /// <summary>
        /// Translation of images.
        /// </summary>
        /// <param name="tranInX">The value translation X.</param>
        /// <param name="tranInY">The value translation in Y.</param>
        /// <returns>the new image</returns>
        public Bitmap Trans_image(int tranInX, int tranInY)
        {
            Bitmap new_Image;
            try
            {
                new_Image = new Bitmap(BufferOfImage.GetLength(0), BufferOfImage.GetLength(1));
                Color[,] newBuffer = new Color[BufferOfImage.GetLength(0), BufferOfImage.GetLength(1)];
                this.CalcTransInYX(tranInY, tranInX, newBuffer, new_Image);
                this.CalcTransFLoop(tranInX, tranInY, newBuffer, new_Image);
                this.CalcTransFLoopX(tranInX, tranInY, newBuffer, new_Image);
                this.CalcTransFLoopY(tranInX, tranInY, newBuffer, new_Image);
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                new_Image = null;
            }

            return new_Image;
        }

        /// <summary>
        /// Calcs the translation in the range found rotation and for not comman rotation between y and x in y only.
        /// </summary>
        /// <param name="tranInX">The tranlation value in X.</param>
        /// <param name="tranInY">The tranlation value in Y.</param>
        /// <param name="newBuffer">The new buffer of new image .</param>
        /// <param name="new_Image">The new_ image.</param>
        private void CalcTransFLoopY(int tranInX, int tranInY, Color[,] newBuffer, Bitmap new_Image)
        {
            int start_x;
            int start_y;
            int end_x;
            int end_y;
            int paraOfX;
            int paraOfY;
            if (tranInX > 0)
            {
                start_x = tranInX;
                end_x = BufferOfImage.GetLength(0);
                paraOfX = tranInX;
            }
            else
            {
                start_x = 0;
                end_x = BufferOfImage.GetLength(0) + tranInX;
                paraOfX = tranInX;
            }

            if (tranInY > 0)
            {
                start_y = 0;
                end_y = tranInY;
                paraOfY = BufferOfImage.GetLength(1) - tranInY;
            }
            else
            {
                start_y = BufferOfImage.GetLength(1) + tranInY - 1;
                end_y = BufferOfImage.GetLength(1) - 1;
                paraOfY = -start_y;
            }

            for (int j = start_x; j < end_x; j++)
            {
                for (int i = start_y; i < end_y; i++)
                {
                    newBuffer[j, i] = BufferOfImage[Math.Abs(paraOfX - j), Math.Abs(paraOfY + i)];
                    new_Image.SetPixel(j, i, newBuffer[j, i]);
                }
            }
        }

        /// <summary>
        /// Calcs the translation in the range found rotation and for not comman rotation between y and x in x only.
        /// </summary>
        /// <param name="tranInX">The tranlation value in X.</param>
        /// <param name="tranInY">The tranlation value in Y.</param>
        /// <param name="newBuffer">The new buffer of new image .</param>
        /// <param name="new_Image">The new_ image.</param>
        private void CalcTransFLoopX(int tranInX, int tranInY, Color[,] newBuffer, Bitmap new_Image)
        {
            int start_x;
            int start_y;
            int end_x;
            int end_y;
            int paraOfX;
            int paraOfY;
            if (tranInX > 0)
            {
                start_x = 0;
                end_x = Math.Abs(tranInX);
                paraOfX = BufferOfImage.GetLength(0) - tranInX;
            }
            else
            {
                start_x = BufferOfImage.GetLength(0) + tranInX - 1;
                end_x = BufferOfImage.GetLength(0) - 1;
                paraOfX = -start_x;
            }

            if (tranInY > 0)
            {
                start_y = tranInY;
                end_y = BufferOfImage.GetLength(1);
                paraOfY = tranInY;
            }
            else
            {
                start_y = 0;
                end_y = BufferOfImage.GetLength(1) + tranInY;
                paraOfY = tranInY;
            }

            for (int j = start_x; j < end_x; j++)
            {
                for (int i = start_y; i < Math.Abs(end_y); i++)
                {
                    newBuffer[j, i] = BufferOfImage[Math.Abs(paraOfX + j), Math.Abs(paraOfY - i)];
                    new_Image.SetPixel(j, i, newBuffer[j, i]);
                }
            }
        }

        /// <summary>
        /// Calcs the translation in simple translation in x and y.
        /// </summary>
        /// <param name="tranInX">The tranlation value in X.</param>
        /// <param name="tranInY">The tranlation value in Y.</param>
        /// <param name="newBuffer">The new buffer of new image.</param>
        /// <param name="new_Image">The new_ image.</param>
        private void CalcTransFLoop(int tranInX, int tranInY, Color[,] newBuffer, Bitmap new_Image)
        {
            int start_x;
            int start_y;
            int end_x;
            int end_y;
            int paraOfX;
            int paraOfY;
            if (tranInX > 0)
            {
                start_x = 0;
                end_x = tranInX;
                paraOfX = BufferOfImage.GetLength(0) - tranInX;
            }
            else
            {
                start_x = BufferOfImage.GetLength(0) + tranInX;
                end_x = BufferOfImage.GetLength(0);
                paraOfX = start_x;
            }

            if (tranInY > 0)
            {
                start_y = 0;
                end_y = tranInY;
                paraOfY = BufferOfImage.GetLength(1) - tranInY;
            }
            else
            {
                start_y = BufferOfImage.GetLength(1) + tranInY;
                end_y = BufferOfImage.GetLength(1) - 1;
                paraOfY = -start_y;
            }

            for (int i = start_y; i < end_y; i++)
            {
                for (int j = start_x; j < end_x; j++)
                {
                    newBuffer[j, i] = BufferOfImage[Math.Abs(paraOfX - j), Math.Abs(paraOfY + i)];
                    new_Image.SetPixel(j, i, newBuffer[j, i]);
                }
            }
        }

        /// <summary>
        /// Calclate the translation in comman regin between YX in indirect translation.
        /// </summary>
        /// <param name="transInY">The translation value in Y.</param>
        /// <param name="transInX">The translation value in X.</param>
        /// <param name="newBuffer">The new buffer of new image.</param>
        /// <param name="im">The new_ image.</param>
        private void CalcTransInYX(int transInY, int transInX, Color[,] newBuffer, Bitmap im)
        {
            int start_y;
            int end_y;
            int start_x;
            int end_x;
            if (transInY < 0)
            {
                start_y = 0;
                end_y = BufferOfImage.GetLength(1) + transInY;
            }
            else
            {
                start_y = transInY;
                end_y = BufferOfImage.GetLength(1);
            }

            if (transInX < 0)
            {
                start_x = 0;
                end_x = BufferOfImage.GetLength(0) + transInX;
            }
            else
            {
                start_x = transInX;
                end_x = BufferOfImage.GetLength(0);
            }

            for (int i = start_y; i < end_y; i++)
            {
                for (int j = start_x; j < end_x; j++)
                {
                    newBuffer[j, i] = BufferOfImage[j - transInX, i - transInY];
                    im.SetPixel(j, i, newBuffer[j, i]);
                }
            }
        }
    }
}